<?php

namespace app\admin\controller;

use app\admin\model\Orders as OrdersModel;
use app\common\controller\Backend;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\model\Category;
use app\common\service\Shop as ShopService;
use app\common\service\OrderStatus;
use fast\Random;
use think\addons\Service;
use think\Cache;
use think\Config;
use think\Db;
use think\Lang;
use think\Loader;
use think\Response;
use think\Validate;

/**
 * Ajax异步请求接口
 * @internal
 */
class Ajax extends Backend
{
    protected $noNeedLogin = ['lang'];
    protected $noNeedRight = ['*'];
    protected $layout = '';

    public function _initialize()
    {
        parent::_initialize();

        //设置过滤方法
        $this->request->filter(['trim', 'strip_tags', 'htmlspecialchars']);
    }

    /**
     * 加载语言包
     */
    public function lang()
    {
        $this->request->get(['callback' => 'define']);
        $header = ['Content-Type' => 'application/javascript'];
        if (!config('app_debug')) {
            $offset = 30 * 60 * 60 * 24; // 缓存一个月
            $header['Cache-Control'] = 'public';
            $header['Pragma'] = 'cache';
            $header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
        }

        $controllername = $this->request->get('controllername');
        $lang = $this->request->get('lang');
        if (!$lang || !in_array($lang, config('allow_lang_list')) || !$controllername || !preg_match("/^[a-z0-9_\.]+$/i", $controllername)) {
            return jsonp(['errmsg' => '参数错误'], 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
        }

        $controllername = input("controllername");
        $className = Loader::parseClass($this->request->module(), 'controller', $controllername, false);

        //存在对应的类才加载
        if (class_exists($className)) {
            $this->loadlang($controllername);
        }

        return jsonp(Lang::get(), 200, $header, ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
    }

    /**
     * 上传文件
     */
    public function upload()
    {
        Config::set('default_return_type', 'json');

        //必须还原upload配置,否则分片及cdnurl函数计算错误
        Config::load(APP_PATH . 'extra/upload.php', 'upload');

        $chunkid = $this->request->post("chunkid");
        if ($chunkid) {
            if (!Config::get('upload.chunking')) {
                $this->error(__('Chunk file disabled'));
            }
            $action = $this->request->post("action");
            $chunkindex = $this->request->post("chunkindex/d");
            $chunkcount = $this->request->post("chunkcount/d");
            $filename = $this->request->post("filename");
            $method = $this->request->method(true);
            if ($action == 'merge') {
                $attachment = null;
                //合并分片文件
                try {
                    $upload = new Upload();
                    $attachment = $upload->merge($chunkid, $chunkcount, $filename);
                } catch (UploadException $e) {
                    $this->error($e->getMessage());
                }
                $this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
            } elseif ($method == 'clean') {
                //删除冗余的分片文件
                try {
                    $upload = new Upload();
                    $upload->clean($chunkid);
                } catch (UploadException $e) {
                    $this->error($e->getMessage());
                }
                $this->success();
            } else {
                //上传分片文件
                //默认普通上传文件
                $file = $this->request->file('file');
                try {
                    $upload = new Upload($file);
                    $upload->chunk($chunkid, $chunkindex, $chunkcount);
                } catch (UploadException $e) {
                    $this->error($e->getMessage());
                }
                $this->success();
            }
        } else {
            $attachment = null;
            //默认普通上传文件
            $file = $this->request->file('file');
            try {
                $upload = new Upload($file);
                $attachment = $upload->upload();
            } catch (UploadException $e) {
                $this->error($e->getMessage());
            }

            $this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
        }
    }

    /**
     * 通用排序
     */
    public function weigh()
    {
        //排序的数组
        $ids = $this->request->post("ids");
        //拖动的记录ID
        $changeid = $this->request->post("changeid");
        //操作字段
        $field = $this->request->post("field");
        //操作的数据表
        $table = $this->request->post("table");
        if (!Validate::is($table, "alphaDash")) {
            $this->error();
        }
        //主键
        $pk = $this->request->post("pk");
        //排序的方式
        $orderway = strtolower($this->request->post("orderway", ""));
        $orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
        $sour = $weighdata = [];
        $ids = explode(',', $ids);
        $prikey = $pk && preg_match("/^[a-z0-9\-_]+$/i", $pk) ? $pk : (Db::name($table)->getPk() ?: 'id');
        $pid = $this->request->post("pid", "");
        //限制更新的字段
        $field = in_array($field, ['weigh']) ? $field : 'weigh';

        // 如果设定了pid的值,此时只匹配满足条件的ID,其它忽略
        if ($pid !== '') {
            $hasids = [];
            $list = Db::name($table)->where($prikey, 'in', $ids)->where('pid', 'in', $pid)->field("{$prikey},pid")->select();
            foreach ($list as $k => $v) {
                $hasids[] = $v[$prikey];
            }
            $ids = array_values(array_intersect($ids, $hasids));
        }

        $list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
        foreach ($list as $k => $v) {
            $sour[] = $v[$prikey];
            $weighdata[$v[$prikey]] = $v[$field];
        }
        $position = array_search($changeid, $ids);
        $desc_id = $sour[$position] ?? end($sour);    //移动到目标的ID值,取出所处改变前位置的值
        $sour_id = $changeid;
        $weighids = [];
        $temp = array_values(array_diff_assoc($ids, $sour));
        foreach ($temp as $m => $n) {
            if ($n == $sour_id) {
                $offset = $desc_id;
            } else {
                if ($sour_id == $temp[0]) {
                    $offset = $temp[$m + 1] ?? $sour_id;
                } else {
                    $offset = $temp[$m - 1] ?? $sour_id;
                }
            }
            if (!isset($weighdata[$offset])) {
                continue;
            }
            $weighids[$n] = $weighdata[$offset];
            Db::name($table)->where($prikey, $n)->update([$field => $weighdata[$offset]]);
        }
        $this->success();
    }

    /**
     * 清空系统缓存
     */
    public function wipecache()
    {
        try {
            $type = $this->request->request("type");
            switch ($type) {
                case 'all':
                case 'content':
                    //内容缓存
                    rmdirs(CACHE_PATH, false);
                    Cache::clear();
                    if ($type == 'content') {
                        break;
                    }
                    // no break
                case 'template':
                    // 模板缓存
                    rmdirs(TEMP_PATH, false);
                    if ($type == 'template') {
                        break;
                    }
                    // no break
                case 'addons':
                    // 插件缓存
                    Service::refresh();
                    if ($type == 'addons') {
                        break;
                    }
                    // no break
                case 'browser':
                    // 浏览器缓存
                    // 只有生产环境下才修改
                    if (!config('app_debug')) {
                        $version = config('site.version');
                        $newversion = preg_replace_callback("/(.*)\.([0-9]+)\$/", function ($match) {
                            return $match[1] . '.' . ($match[2] + 1);
                        }, $version);
                        if ($newversion && $newversion != $version) {
                            Db::startTrans();
                            try {
                                \app\common\model\Config::where('name', 'version')->update(['value' => $newversion]);
                                \app\common\model\Config::refreshFile();
                                Db::commit();
                            } catch (\Exception $e) {
                                Db::rollback();
                                exception($e->getMessage());
                            }
                        }
                    }
                    if ($type == 'browser') {
                        break;
                    }
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }

        \think\Hook::listen("wipecache_after");
        $this->success();
    }

    /**
     * 读取分类数据,联动列表
     */
    public function category()
    {
        $type = $this->request->get('type', '');
        $where = ['status' => 'normal'];
        $categorylist = null;
        if ($type) {
            $where['type'] = $type;
        }
        $category = new Category;
        $categorylist = $category->getTypeList();
        // $categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select();
        // { 0: __("Status 0"), 1: __("Status 1") }
        // $this->success('', '', $categorylist);
        return json($categorylist);
    }

    /**
     * 读取省市区数据,联动列表
     */
    public function area()
    {
        $params = $this->request->get("row/a");
        if (!empty($params)) {
            $province = isset($params['province']) ? $params['province'] : null;
            $city = isset($params['city']) ? $params['city'] : null;
        } else {
            $province = $this->request->get('province');
            $city = $this->request->get('city');
        }
        $where = ['pid' => 0, 'level' => 1];
        $provincelist = null;
        if ($province !== null) {
            $where['pid'] = $province;
            $where['level'] = 2;
            if ($city !== null) {
                $where['pid'] = $city;
                $where['level'] = 3;
            }
        }
        $provincelist = Db::name('area')->where($where)->field('id as value,name')->select();
        $this->success('', '', $provincelist);
    }

    /**
     * 生成后缀图标
     */
    public function icon()
    {
        $suffix = $this->request->request("suffix");
        $suffix = $suffix ? $suffix : "FILE";
        $data = build_suffix_image($suffix);
        $header = ['Content-Type' => 'image/svg+xml'];
        $offset = 30 * 60 * 60 * 24; // 缓存一个月
        $header['Cache-Control'] = 'public';
        $header['Pragma'] = 'cache';
        $header['Expires'] = gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
        $response = Response::create($data, '', 200, $header);
        return $response;
    }

    /**
     * 设置店铺状态
     *
     */
    public function shopSetStatus()
    {
        $status = $this->request->post('status');
        try {
            $statusService = new ShopService();
            $statusService->setStatus($status);

            // 触发Workerman推送
            // 建立socket连接到内部推送端口
            $client = stream_socket_client('tcp://127.0.0.1:5679', $errno, $errmsg, 1);
            // 推送的数据，包含uid字段，表示是给这个uid推送
            // 2. 构造推送消息（符合前端约定的JSON格式）
            $data = [
                'uid' => 'uid1',
                'status'   => $status, // 状态
            ];
            // 发送数据，注意5678端口是Text协议的端口，Text协议需要在数据末尾加上换行符
            fwrite($client, json_encode($data) . "\n");
            // 读取推送结果
            fread($client, 8192);
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('设置成功', null, ['status' => $status]);
    }

    /**
     * 读取菜品分类联动
     */
    public function dishCategory()
    {
        try {
            $result = [];
            // 分类模型
            $list = Category::all(function ($query) {
                $query->where('type', 1)->where('status', 1)->order('createtime', 'desc');
            });
            // 处理分类数据
            foreach ($list as $key => $category) {
                $dishes = $category->adminDishes()->field('id,name,price,status')->select();
                if (!empty($dishes)) {
                    $result[] = [
                        'categoryId' => $category->id,
                        'categoryName' => $category->name,
                        'dishes' => $dishes,
                    ];
                }
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('', '', $result);
    }

    /**
     * 获取订单状态对应总数
     *
     */
    public function getStatusCounts()
    {
        // 1. 按状态分组统计订单数（根据你的实际字段调整）
        $counts = OrdersModel::field('status, COUNT(*) AS count')
            ->group('status')
            ->select();

        // 2. 转成数组（FastAdmin 的模型查询结果默认是 Collection，需转数组）
        // $data = $counts->toArray();

        // 3. 返回 JSON（code=1 表示成功，data 是状态-计数列表）
        return json(['code' => 1, 'data' => $counts]);
    }

    /**
     * 取消订单
     *
     */
    public function cancelOrder($ids)
    {
        //验证数据合法性
        $data = $this->request->post();
        $data['id'] = $ids;
        $validate = Loader::validate('Orders');
        if (!$validate->scene('cancel')->check($data)) {
            return json([
                'code' => 0,
                'msg' => $validate->getError(),
                'data' => null
            ]);
        }
        $order =  OrdersModel::get($ids);
        if (!$order) {
            return json([
                'code' => 0,
                'msg' => '没有找到订单',
                'data' => null
            ]);
        }
        $order->status = OrderStatus::CANCELLED;
        $order->cancel_reason = $data['cancelReason'];
        $order->cancel_reason = date('Y-m-d H:i:s');
        $order->save();
        return json([
            'code' => 1,
            'msg' => '取消订单成功',
            'data' => null
        ]);
    }

    /**
     * 退单
     *
     */
    public function returnOrder($ids)
    {
        //验证数据合法性
        $data['id'] = $ids;
        $validate = Loader::validate('Orders');
        if (!$validate->scene('return')->check($data)) {
            return json([
                'code' => 0,
                'msg' => $validate->getError(),
                'data' => null
            ]);
        }
        $order =  OrdersModel::get($ids);
        if (!$order) {
            return json([
                'code' => 0,
                'msg' => '没有找到订单',
                'data' => null
            ]);
        }
        $order->status = OrderStatus::CANCELLED;
        $order->cancel_reason = date('Y-m-d H:i:s');
        $order->save();
        return json([
            'code' => 1,
            'msg' => '退单成功',
            'data' => null
        ]);
    }

    /**
     * 拒绝订单
     *
     */
    public function rejectionOrder($ids)
    {
        //验证数据合法性
        $data = $this->request->post();
        $data['id'] = $ids;
        $validate = Loader::validate('Orders');
        if (!$validate->scene('rejection')->check($data)) {
            return json([
                'code' => 0,
                'msg' => $validate->getError(),
                'data' => null
            ]);
        }
        $order =  OrdersModel::get($ids);
        if (!$order) {
            return json([
                'code' => 0,
                'msg' => '没有找到订单',
                'data' => null
            ]);
        }
        $order->status = OrderStatus::CANCELLED;
        $order->rejection_reason = $data['rejectionReason'];
        $order->cancel_reason = date('Y-m-d H:i:s');
        $order->save();
        return json([
            'code' => 1,
            'msg' => '拒绝订单成功',
            'data' => null
        ]);
    }

    /**
     * 接取订单
     *
     */
    public function acceptOrder($ids)
    {
        //验证数据合法性
        $data['id'] = $ids;
        $validate = Loader::validate('Orders');
        if (!$validate->scene('accept')->check($data)) {
            return json([
                'code' => 0,
                'msg' => $validate->getError(),
                'data' => null
            ]);
        }
        $order =  OrdersModel::get($ids);
        if (!$order) {
            return json([
                'code' => 0,
                'msg' => '没有找到订单',
                'data' => null
            ]);
        }
        $order->status = OrderStatus::CONFIRMED;
        $order->save();
        return json([
            'code' => 1,
            'msg' => '接取订单成功',
            'data' => null
        ]);
    }

    /**
     * 派送
     *
     */
    public function deliveryOrder($ids)
    {
        //验证数据合法性
        $data['id'] = $ids;
        $validate = Loader::validate('Orders');
        if (!$validate->scene('delivery')->check($data)) {
            return json([
                'code' => 0,
                'msg' => $validate->getError(),
                'data' => null
            ]);
        }
        $order =  OrdersModel::get($ids);
        if (!$order) {
            return json([
                'code' => 0,
                'msg' => '没有找到订单',
                'data' => null
            ]);
        }
        $order->status = OrderStatus::DELIVERY_IN_PROGRESS;
        $order->save();
        return json([
            'code' => 1,
            'msg' => '派送订单成功',
            'data' => null
        ]);
    }

    /**
     * 完成订单
     *
     */
    public function compOrder($ids)
    {
        //验证数据合法性
        $data['id'] = $ids;
        $validate = Loader::validate('Orders');
        if (!$validate->scene('comp')->check($data)) {
            return json([
                'code' => 0,
                'msg' => $validate->getError(),
                'data' => null
            ]);
        }
        $order =  OrdersModel::get($ids);
        if (!$order) {
            return json([
                'code' => 0,
                'msg' => '没有找到订单',
                'data' => null
            ]);
        }
        $order->status = OrderStatus::COMPLETED;
        $order->delivery_time = date('Y-m-d H:i:s');
        $order->save();
        return json([
            'code' => 1,
            'msg' => '订单完成',
            'data' => null
        ]);
    }
}
